﻿Imports System
Imports System.ComponentModel
Imports System.Runtime.InteropServices
Imports System.Windows.Forms
Imports System.Globalization

''' <summary>
''' bla bla bla 
''' </summary>
<ComVisible(False)> _
Public Class dmnCalender

    Enum enmZoomMode
        'Year
        'Month
        Week
        Hour_6
        Hour_4
        Hour
        HalfHour
        Min_15
    End Enum
#Region "****************************************************************************** Constructor"
    Sub New()

        ' This call is required by the Windows Form Designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
        comZoom.Items.Clear()

        For Each zoom As dmnCalender.enmZoomMode In [Enum].GetValues(GetType(dmnCalender.enmZoomMode))
            comZoom.Items.Add(zoom)
        Next
        comZoom.SelectedItem = enmZoomMode.Hour
        DateTimePicker1.Value = Date.Now
        CreateContextMenu()

        Show()
    End Sub
#End Region

#Region "****************************************************************************** Private "
    Private _Zoom As enmZoomMode = enmZoomMode.Hour
    Private _WorkDayStart As Date = DateAndTime.DateValue("7:00")
    Private _WorkDayEnd As Date = DateAndTime.DateValue("17:30")
    Private _dvEvents As DataView
    Private _dvDayProperties As DataView
    Private _SystemID As Int32 = -1
    Private TimeValue As Int32 = 60
    Private WithEvents lmnuContextMenu As New ContextMenu
    Private _ActiveColour As Color = Color.WhiteSmoke
    Private _InActiveColour As Color = Color.LightGray
    Private ActiveColour As Color = Color.WhiteSmoke
    Private InActiveColour As Color = Color.LightGray
    Private lStartOfDayPos As Integer = 0

    Private Sub CreateContextMenu()

        lmnuContextMenu.MenuItems.Add("Add New Item", New System.EventHandler(AddressOf AddNewItemToTimeSlot))        
        'lmnuContextMenu.MenuItems.Add("Day Properties", New System.EventHandler(AddressOf TimeSlotProperties))
        lmnuContextMenu.MenuItems.Add("Time slot Non Working", New System.EventHandler(AddressOf TimeSlotPropertiesNonWorking))
        lmnuContextMenu.MenuItems.Add("Time slot Working", New System.EventHandler(AddressOf TimeSlotPropertiesWorking))

    End Sub

    Private Sub TimeSlotPropertiesNonWorking(ByVal sender As Object, ByVal e As System.EventArgs)       
        Dim lpnl As Panel = CType(lmnuContextMenu.Tag, Panel)

        _dvDayProperties.Table.Rows.Add()
        Dim dt As DataTable = _dvDayProperties.Table
        Dim dr As DataRow = dt.NewRow

        dr("StartDateTime") = Split(lpnl.Tag, "|")(0)
        dr("EndDateTime") = Split(lpnl.Tag, "|")(1)
        dr("FullDay") = 0

        dt.Rows.Add(dr)

    End Sub

    Private Sub TimeSlotPropertiesWorking(ByVal sender As Object, ByVal e As System.EventArgs)        
        Dim lpnl As Panel = CType(lmnuContextMenu.Tag, Panel)
    End Sub

    Private Function GetBGColour(ByRef pnl As Panel, ByRef pDate As Date) As Color
        Dim Filter As String = String.Empty
        Dim lStartTime As Long = Split(pnl.Tag, "|")(0)
        Dim lEndTime As Long = Split(pnl.Tag, "|")(1)
        Dim retColour As Color = _ActiveColour

        If lStartTime < _WorkDayStart.ToOADate Then
            retColour = _InActiveColour
        ElseIf lStartTime > _WorkDayEnd.ToOADate Then
            retColour = InActiveColour
            If lStartOfDayPos = 0 Then lStartOfDayPos = pnl.Top
        Else
            retColour = ActiveColour
        End If

        If _dvDayProperties IsNot Nothing Then
            Filter = String.Format("(StartDateTime >= {0} AND EndDateTime <= {1} AND FullDay = 1) ", _
                                       pDate.ToOADate, _
                                       DateAdd(DateInterval.Day, 1, pDate).ToOADate)
            _dvDayProperties.RowFilter = Filter

            If _dvDayProperties.Count > 0 Then
                retColour = _InActiveColour                
            Else
                retColour = _ActiveColour
            End If

            Filter = String.Format("(StartDateTime >= {0} AND EndDateTime <= {1} ) ", _
                                           lStartTime, _
                                           lEndTime)

            Filter &= String.Format("OR (StartDateTime <= {0} AND EndDateTime >= {1} ) ", _
                                   lEndTime, _
                                   lStartTime)

            _dvDayProperties.RowFilter = Filter

            If _dvDayProperties.Count > 0 Then
                retColour = _InActiveColour
            Else
                retColour = _ActiveColour
            End If
            _dvDayProperties.RowFilter = ""
        End If

        Return retColour
    End Function

    Private Sub LoadDataGrid()

        Dim oDataSetHelper As New DataSetHelper

        Dim filter As String
        Dim splitValue As Int32 = 0
        Dim lDays As Integer = 1
        Dim tmeTime As Date = Date.MinValue
        Dim lBackColor As Color = Color.Wheat

        splitValue = 24
        If _Zoom = enmZoomMode.Hour Then
            splitValue = 24
            TimeValue = 60
        ElseIf _Zoom = enmZoomMode.HalfHour Then
            splitValue = 48
            TimeValue = 30
        ElseIf _Zoom = enmZoomMode.Min_15 Then
            splitValue = 96
            TimeValue = 15
        ElseIf _Zoom = enmZoomMode.Hour_4 Then
            splitValue = 6
            TimeValue = 240
        ElseIf _Zoom = enmZoomMode.Hour_6 Then
            splitValue = 4
            TimeValue = 360
        ElseIf _Zoom = enmZoomMode.Week Then
            splitValue = 24
            TimeValue = 60
            lDays = 7
        Else
            splitValue = 1
            TimeValue = 1440
        End If
        pnlDetail1.Enabled = False
        pnlDetail1.Visible = False

        Application.DoEvents()
        pnlDetail1.HorizontalScroll.Value = 0
        pnlDetail1.VerticalScroll.Value = 0
        pnlMain.Controls.Clear()
        pnlHeader.Controls.Clear()
        pnlMain.Left = 0
        pnlMain.Top = 0
        pnlMain.Width = pnlDetail1.Width

        pnlMain.Height = 2000
        lStartOfDayPos = 0
        For iDays As Integer = 1 To lDays
            Dim DayTag As String = iDays
            Dim pnlDay As New Panel
            Dim lblDayLabel As New Label
            Dim lDate As Date = DateAdd(DateInterval.Day, iDays - 1, DateTimePicker1.Value.Date)

            pnlDay.Controls.Clear()
            pnlDay.Parent = pnlMain
            pnlDay.Width = pnlDay.Parent.Width / (lDays + 1)
            pnlDay.Top = 0
            pnlDay.Left = (iDays - 1) * pnlDay.Width
            pnlDay.Height = pnlDay.Parent.Height

            lblDayLabel.Parent = pnlHeader
            lblDayLabel.Left = pnlDay.Left
            lblDayLabel.Width = pnlDay.Width
            lblDayLabel.Text = Format(lDate, "ddd dd")
            lblDayLabel.BorderStyle = Windows.Forms.BorderStyle.FixedSingle
            lblDayLabel.TextAlign = ContentAlignment.MiddleCenter

            Dim pnlDayDetail As New Panel
            ' Day ***********************************************************        
            pnlDayDetail.Controls.Clear()
            pnlDayDetail.Parent = pnlDay
            pnlDayDetail.Left = 0
            pnlDayDetail.Top = 0
            pnlDayDetail.Height = 20
            pnlDayDetail.Height = 20 * (splitValue + 2)
            pnlDayDetail.Width = pnlDayDetail.Parent.Width
            pnlDayDetail.Tag = DayTag

            pnlDayDetail.BorderStyle = BorderStyle.FixedSingle
            pnlDayDetail.HorizontalScroll.Enabled = False
            pnlDayDetail.VerticalScroll.Enabled = False
            Application.DoEvents()
            tmeTime = Date.MinValue
            _WorkDayStart = FormatDateTime(lDate.ToString, DateFormat.ShortDate) & " 07:00 AM"
            _WorkDayEnd = FormatDateTime(lDate.ToString, DateFormat.ShortDate) & " 17:00 PM"


            For iTimeSlot As Int32 = 1 To splitValue
                Dim timeSlot1 As New Panel
                Dim TimeSlotTagStart As Date = FormatDateTime(lDate.ToString, DateFormat.ShortDate) & " " & FormatDateTime(tmeTime, DateFormat.LongTime)
                Dim TimeSlotTagEnd As Date = FormatDateTime(lDate.ToString, DateFormat.ShortDate) & " " & FormatDateTime(tmeTime, DateFormat.LongTime)
                TimeSlotTagEnd = DateAdd(DateInterval.Minute, TimeValue - 1, TimeSlotTagEnd)

                timeSlot1.Parent = pnlDayDetail
                timeSlot1.BorderStyle = BorderStyle.FixedSingle
                timeSlot1.Height = 20
                timeSlot1.Width = 300
                timeSlot1.Left = 0
                timeSlot1.Top = (iTimeSlot - 1) * timeSlot1.Height
                timeSlot1.Tag = TimeSlotTagStart.ToOADate & "|" & TimeSlotTagEnd.ToOADate

                AddHandler timeSlot1.MouseDown, AddressOf UpdateTimeSlot

                timeSlot1.BackColor = GetBGColour(timeSlot1, lDate)

                Dim _txt As New Label
                _txt.Parent = timeSlot1
                _txt.Left = 0
                _txt.Top = 0
                _txt.Width = 40 ' _txt.Parent.Width
                _txt.Height = _txt.Parent.Height
                _txt.TextAlign = ContentAlignment.MiddleRight
                _txt.Text = FormatDateTime(tmeTime, DateFormat.ShortTime)
                _txt.BorderStyle = Windows.Forms.BorderStyle.FixedSingle

                Dim _Icon As New PictureBox
                _Icon.Parent = timeSlot1
                _Icon.Image = ImageList1.Images("Default")
                _Icon.Height = timeSlot1.Height
                _Icon.Width = 40                
                _Icon.Top = 0
                _Icon.Left = 0
                _Icon.BringToFront()

                If _dvEvents IsNot Nothing Then

                    filter = String.Format("(StartDateTime >= {0} AND EndDateTime <= {1} ) ", _
                                           TimeSlotTagStart.ToOADate, _
                                           TimeSlotTagEnd.ToOADate)

                    filter &= String.Format("OR (StartDateTime <= {0} AND EndDateTime >= {1} ) ", _
                                           TimeSlotTagEnd.ToOADate, _
                                           TimeSlotTagStart.ToOADate)

                    _dvEvents.RowFilter = "SystemID = " & _SystemID.ToString & " AND " & filter                    '" AND (StartDateTime >= " & TimeSlotTag & " " & _
                    If _dvEvents.Count > 0 Then
                        AddNewItemToTimeSlot(timeSlot1, Nothing)
                    End If
                End If

                tmeTime = DateAdd(DateInterval.Minute, TimeValue, tmeTime)
            Next
        Next
        pnlDetail1.Enabled = True
        pnlDetail1.Visible = True
        pnlDetail1.VerticalScroll.Minimum = 0
        pnlDetail1.VerticalScroll.Maximum = pnlMain.Height
        pnlDetail1.VerticalScroll.Value = lStartOfDayPos
        pnlMain.Top = lStartOfDayPos * -1

    End Sub

    Private Sub AddNewItemToTimeSlot(ByVal sender As Object, ByVal e As System.EventArgs)

        Dim btn As New Button
        Dim lpnl As Panel = CType(lmnuContextMenu.Tag, Panel)
        If _SystemID = -1 Then Exit Sub
        For Each ctr As Control In lpnl.Controls
            If TypeOf ctr Is Button Then                
                Exit Sub
            End If
        Next
        btn.Parent = lpnl
        btn.Height = lpnl.Height
        btn.Left = 40
        btn.Top = 0
        btn.Width = 120
        btn.Text = CType(Date.FromOADate(Split(lpnl.Tag, "|")(0)), Date).ToString
        AddHandler btn.Click, AddressOf ViewEvent

        If e IsNot Nothing Then
            _dvEvents.Table.Rows.Add()
            Dim dt As DataTable = _dvEvents.Table
            Dim dr As DataRow = dt.NewRow

            dr("SystemID") = _SystemID
            dr("StartDateTime") = Split(lpnl.Tag, "|")(0)
            dr("EndDateTime") = Split(lpnl.Tag, "|")(1)
            dr("Name") = CType(Date.FromOADate(Split(lpnl.Tag, "|")(0)), Date).ToString

            dt.Rows.Add(dr)
        End If
    End Sub

    Private Sub UpdateTimeSlot(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
        CType(sender, Panel).ContextMenu = lmnuContextMenu
        lmnuContextMenu.Tag = sender
        'AddNewItemToTimeSlot(sender, e)
    End Sub

    Private Sub ViewEvent(ByVal sender As Object, ByVal e As System.EventArgs)
        Dim oFrm As New frmDetail
        oFrm.TextBox1.Text = CType(sender, Button).Text
        oFrm.ShowDialog()
    End Sub

    Private Sub comZoom_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles comZoom.SelectedIndexChanged
        Zoom = comZoom.SelectedItem
        Show()
    End Sub

    Private Sub DateTimePicker1_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DateTimePicker1.ValueChanged
        Zoom = comZoom.SelectedItem
        Show()
    End Sub

#End Region


#Region "****************************************************************************** Properties"
    <Browsable(False)> _
    <DefaultValue(-1)> _
    Public Property SystemID() As Int32
        Get
            Return _SystemID
        End Get
        Set(ByVal value As Int32)
            _SystemID = value
        End Set
    End Property

    <Browsable(False)> _
    Public Property dvEvents() As DataView
        Get
            Return _dvEvents
        End Get
        Set(ByVal value As DataView)
            _dvEvents = value
        End Set
    End Property

    <Browsable(False)> _
    Public Property dvDayProperties() As DataView
        Get
            Return _dvDayProperties
        End Get
        Set(ByVal value As DataView)
            _dvDayProperties = value
        End Set
    End Property


    <Browsable(True)> _
    <DefaultValue("7:00")> _
    <Category("Behavior")> _
    <Description("Start of work day")> _
    Public Property WorkDayStart() As String
        Get
            Return _WorkDayStart
        End Get
        Set(ByVal value As String)
            _WorkDayStart = value
        End Set
    End Property

    <Browsable(True)> _
    <DefaultValue("16:30")> _
    <Category("Behavior")> _
    <Description("End of work day")> _
    Public Property WorkDayEnd() As String
        Get
            Return _WorkDayEnd
        End Get
        Set(ByVal value As String)
            _WorkDayEnd = value
        End Set
    End Property

    <Browsable(True)> _
    <DefaultValue(enmZoomMode.Hour)> _
    <Category("Behavior")> _
    <Description("Zoom level")> _
    Public Property Zoom() As enmZoomMode
        Get
            Return _Zoom
        End Get
        Set(ByVal value As enmZoomMode)
            _Zoom = value
        End Set
    End Property

    Public Shadows Sub Show()
        LoadDataGrid()
    End Sub
#End Region



End Class


